home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / oper_sys / emerald / emrldsys.lha / Language / Compiler / ident.c < prev    next >
C/C++ Source or Header  |  1990-08-16  |  4KB  |  164 lines

  1. /*
  2.  * @(#)ident.c    1.3  9/24/87
  3.  */
  4. #include <stdio.h>
  5. #include "ident.h"
  6. #include "assert.h"
  7.  
  8. #define CASEFOLD
  9.  
  10. char *malloc();
  11.  
  12. #define PAGESIZE 1024
  13. #define identsPerBlock (PAGESIZE)
  14. #define charsPerBlock PAGESIZE
  15.  
  16. #define maxIdentElementBlocks 8
  17.  
  18. typedef struct identElementStruct {
  19.     Ident                this;
  20.     char                   *name;
  21.     struct identElementStruct      *next;
  22. } IdentElement;
  23.  
  24. typedef IdentElement IdentElementBlock[identsPerBlock];
  25. typedef int HashResultType;
  26.  
  27. static Ident nextIdentToAllocate = 0;
  28. static char *fillPtr, *fillBase;
  29.  
  30. static IdentElementBlock *identElementBlockList[maxIdentElementBlocks];
  31.  
  32. static char hashvalues[128] = 
  33. {
  34.   -1, -1, -1, -1, -1, -1, -1, -1,
  35.   -1, -1, -1, -1, -1, -1, -1, -1,
  36.   -1, -1, -1, -1, -1, -1, -1, -1,
  37.   -1, -1, -1, -1, -1, -1, -1, -1,
  38.   -1, 36, -1, 37, -1, -1, 38, -1, 
  39.   -1, -1, 39, 40, -1, 41, -1, 42,
  40.   26, 27, 28, 29, 30, 31, 32, 33,
  41.   34, 35, -1, -1, 43, 44, 45, 46,
  42.   47,  0,  1,  2,  3,  4,  5,  6,
  43.   7,  8,  9, 10, 11, 12, 13, 14,
  44.   15, 16, 17, 18, 19, 20, 21, 22,
  45.   23, 24, 25, -1, -1, -1, 48, 49,
  46.   -1,  0,  1,  2,  3,  4,  5,  6,
  47.   7,  8,  9, 10, 11, 12, 13, 14,
  48.   15, 16, 17, 18, 19, 20, 21, 22,
  49.   23, 24, 25, -1, 50, -1, 51, -1
  50. };
  51.  
  52. #define Value(x) ((int) hashvalues[x])
  53.  
  54. static HashResultType Hash (tokenText)
  55. register char *tokenText;
  56. {
  57. #define R 52
  58.   register int result;
  59.   register int next;
  60.   next = *tokenText++;
  61.   result = Value(next);
  62.   result = result * R;
  63.   if (*tokenText != '\0') {
  64.     next = *tokenText++;
  65.     result = result + Value(next);
  66.   }
  67.   result = result * R;
  68.   if (*tokenText != '\0') {
  69.     next = *tokenText;
  70.     result = result + Value(next);
  71.   }
  72.   return(result);
  73. }
  74. static IdentElement *hashTable[256];
  75.   
  76. Ident Ident_Lookup(tokenText, tokenLength)
  77. char *tokenText;
  78. int tokenLength;
  79. {
  80.   HashResultType x = Hash(tokenText);
  81. #ifdef CASEFOLD
  82.   register char *l, *r;
  83. #endif
  84.   register IdentElement *leader = hashTable[x % 256];
  85.   register IdentElement *follower = NULL;
  86.   register int compareResult;
  87.   register Ident resultIdent = Ident_nil;
  88.       IdentElementBlock **ieb;
  89.   register IdentElement *ie;
  90.  
  91.   while (leader != NULL) {
  92. #ifdef CASEFOLD
  93.     for (l = tokenText, r = leader->name; *l && *r; l++, r++) {
  94.       compareResult = ((*l) & ~0x20) - ((*r) & ~ 0x20);
  95.       if (compareResult) break;
  96.     }
  97.     if (compareResult == 0) compareResult = *l - *r;
  98. #else
  99.     compareResult = strcmp(tokenText, leader->name);
  100. #endif
  101.     if (compareResult == 0) {
  102.       resultIdent = leader->this;
  103.       break;
  104.     } else if (compareResult < 0) {
  105.       break;
  106.     } else {
  107.       follower = leader;
  108.       leader = leader->next;
  109.     }
  110.   }
  111.   if (resultIdent == Ident_nil) {
  112.     resultIdent = nextIdentToAllocate;
  113.     nextIdentToAllocate = nextIdentToAllocate + 1;
  114.     ieb = &identElementBlockList[resultIdent / identsPerBlock];
  115.     if (*ieb == NULL) {
  116.       *ieb = (IdentElementBlock *) malloc(sizeof(IdentElementBlock));
  117.     }
  118.     ie = &((**ieb)[resultIdent % identsPerBlock]);
  119.     if (tokenLength + 1 > charsPerBlock - (fillPtr - fillBase)) {
  120.       fillBase = malloc(charsPerBlock);
  121.       fillPtr = fillBase;
  122.     }
  123.     ie->name = fillPtr;
  124. #ifdef CASEFOLD
  125.     for (l = fillPtr, r = tokenText; *r; l++, r++) {
  126.       if (*r >= 'A' && *r <= 'Z') *l = *r - 'A' + 'a';
  127.       else *l = *r;
  128.     }
  129.     *l = '\0';
  130. #else
  131.     bcopy(tokenText, fillPtr, tokenLength + 1);
  132. #endif CASEFOLD
  133.     fillPtr = fillPtr + tokenLength + 1;
  134.     ie->this = resultIdent;
  135.     ie->next = leader;
  136.     if (follower == NULL) {
  137.       hashTable[x % 256] = ie;
  138.     } else {
  139.       follower->next = ie;
  140.     }
  141.   }
  142.   return (resultIdent);
  143. }
  144.  
  145. void Ident_Initialize()
  146. {
  147.   bzero((char *)hashTable, sizeof(hashTable));
  148.   bzero((char *)identElementBlockList, sizeof(identElementBlockList));
  149.   fillBase = (char *) malloc(charsPerBlock);
  150.   fillPtr = fillBase;
  151. }
  152.  
  153. char *Ident_Name(fIdent)
  154. Ident fIdent;
  155. {
  156.   register IdentElementBlock *ibp;
  157.   if (fIdent == -1) return ("<unknown>");
  158.   else {
  159.     ibp = identElementBlockList[fIdent / identsPerBlock];
  160.     if (ibp == NULL) return(NULL);
  161.     else return ((*ibp)[fIdent % identsPerBlock].name);
  162.   }
  163. }
  164.